# -*- coding:utf-8 -*-
__author__ = 'Dragon Sun'
__date__ = '2025-07-02 17:56:57'

import datetime
from pathlib import Path
from typing import Any

from PySide6.QtCore import QObject
from PySide6.QtGui import QTextCursor
from PySide6.QtWidgets import QLabel, QPlainTextEdit
from dsPySide6.utils.func import load_ui

from src.wss.ds_wss_okxv5 import DSOKXv5WebSocket, 频道枚举, DSWebSocket


class Demo_WSS_OKXv5_视图控制器类(QObject):

    # noinspection PyUnresolvedReferences
    def __init__(self):
        super().__init__()

        # 视图
        视图文件名 = Path(__file__).resolve().parent / 'demo_wss_okxv5.ui'
        self.视图 = load_ui(ui_file=视图文件名, custom_widgets=[], parent=None)

        # 组件映射
        self._公共频道_手动连接时间标签框: QLabel = self.视图.lblPublicConnectTime
        self._公共频道_自动连接次数标签框: QLabel = self.视图.lblPublicConnNum
        self._公共频道_最后一次连接时间标签框: QLabel = self.视图.lblPublicConnLastTime
        self._公共频道_Pong次数标签框: QLabel = self.视图.lblPublicPongNum
        self._公共频道_最后一次Pong时间标签框: QLabel = self.视图.lblPublicPongLastTime
        self._公共频道_错误次数标签框: QLabel = self.视图.lblPublicErrorNum
        self._公共频道_最后一次错误时间标签框: QLabel = self.视图.lblPublicErrorLastTime

        self._私有频道_手动连接时间标签框: QLabel = self.视图.lblPrivateConnectTime
        self._私有频道_自动连接次数标签框: QLabel = self.视图.lblPrivateConnNum
        self._私有频道_最后一次连接时间标签框: QLabel = self.视图.lblPrivateConnLastTime
        self._私有频道_Pong次数标签框: QLabel = self.视图.lblPrivatePongNum
        self._私有频道_最后一次Pong时间标签框: QLabel = self.视图.lblPrivatePongLastTime
        self._私有频道_错误次数标签框: QLabel = self.视图.lblPrivateErrorNum
        self._私有频道_最后一次错误时间标签框: QLabel = self.视图.lblPrivateErrorLastTime

        self._最新价格标签框: QLabel = self.视图.lblLastPrice
        self._标记价格标签框: QLabel = self.视图.lblMarkPrice
        self._最后一次持仓变化时间标签框: QLabel = self.视图.lblPositionLastTime

        self._日志文本框: QPlainTextEdit = self.视图.edtLog

        # 初始化显示
        self._初始化组件状态()

        # WebSocket
        self.wss = DSOKXv5WebSocket()
        self.wss.信号_最新价格更新.connect(self._最新价格更新处理)
        self.wss.信号_标记价格更新.connect(self._标记价格更新处理)
        self.wss.信号_当前持仓变化.connect(self._当前持仓变化处理)
        self.wss.信号_收到USDT余额.connect(self._收到USDT余额处理)
        self.wss.信号_统计数据变化.connect(self._统计数据变化处理)
        self.wss.信号_发生错误.connect(self._发生错误处理)
        self.wss.运行()

    def _最新价格更新处理(self, 最新价格: float):
        self._最新价格标签框.setText(str(最新价格))

    def _标记价格更新处理(self, 标记价格: float):
        self._标记价格标签框.setText(str(标记价格))

    def _当前持仓变化处理(self):
        最后变化时间 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self._最后一次持仓变化时间标签框.setText(最后变化时间)
        self._log('持仓变化')

    def _收到USDT余额处理(self, USDT余额: float):
        self._log(f'USDT余额={USDT余额}')

    def _统计数据变化处理(self, ds_ws: DSWebSocket, 频道: 频道枚举):
        时间格式化串 = '%Y-%m-%d %H:%M:%S'

        手动连接时间 = ds_ws.手动连接时间.strftime(时间格式化串) if ds_ws.手动连接时间 else ''
        自动连接次数 = str(ds_ws.自动连接次数)
        最后连接时间 = ds_ws.最后一次连接时间.strftime(时间格式化串) if ds_ws.最后一次连接时间 else ''
        Pong次数 = str(ds_ws.pong次数)
        最后一次Pong时间 = ds_ws.最后一次pong时间.strftime(时间格式化串) if ds_ws.最后一次pong时间 else ''
        错误次数 = str(ds_ws.错误次数)
        最后一次错误时间 = ds_ws.最后一次错误时间.strftime(时间格式化串) if ds_ws.最后一次错误时间 else ''

        if 频道 == 频道枚举.公共频道:
            self._公共频道_手动连接时间标签框.setText(手动连接时间)
            self._公共频道_自动连接次数标签框.setText(自动连接次数)
            self._公共频道_最后一次连接时间标签框.setText(最后连接时间)
            self._公共频道_Pong次数标签框.setText(Pong次数)
            self._公共频道_最后一次Pong时间标签框.setText(最后一次Pong时间)
            self._公共频道_错误次数标签框.setText(错误次数)
            self._公共频道_最后一次错误时间标签框.setText(最后一次错误时间)

        if 频道 == 频道枚举.私有频道:
            self._私有频道_手动连接时间标签框.setText(手动连接时间)
            self._私有频道_自动连接次数标签框.setText(自动连接次数)
            self._私有频道_最后一次连接时间标签框.setText(最后连接时间)
            self._私有频道_Pong次数标签框.setText(Pong次数)
            self._私有频道_最后一次Pong时间标签框.setText(最后一次Pong时间)
            self._私有频道_错误次数标签框.setText(错误次数)
            self._私有频道_最后一次错误时间标签框.setText(最后一次错误时间)

    def _发生错误处理(self, _: DSWebSocket, 错误: Any, 频道: 频道枚举):
        错误信息 = f'{频道.value}, {错误}'
        self._log(text=错误信息)

    def _初始化组件状态(self):
        self._公共频道_手动连接时间标签框.setText('')
        self._公共频道_自动连接次数标签框.setText('0')
        self._公共频道_最后一次连接时间标签框.setText('')
        self._公共频道_Pong次数标签框.setText('0')
        self._公共频道_最后一次Pong时间标签框.setText('')
        self._公共频道_错误次数标签框.setText('0')
        self._公共频道_最后一次错误时间标签框.setText('')

        self._私有频道_手动连接时间标签框.setText('')
        self._私有频道_自动连接次数标签框.setText('0')
        self._私有频道_最后一次连接时间标签框.setText('')
        self._私有频道_Pong次数标签框.setText('0')
        self._私有频道_最后一次Pong时间标签框.setText('')
        self._私有频道_错误次数标签框.setText('0')
        self._私有频道_最后一次错误时间标签框.setText('')

        self._最新价格标签框.setText('')
        self._标记价格标签框.setText('')
        self._最后一次持仓变化时间标签框.setText('')

        self._日志文本框.clear()

    def _log(self, text: str, 同一行追加: bool = False):
        if 同一行追加:
            cursor = self._日志文本框.textCursor()
            cursor.movePosition(QTextCursor.MoveOperation.End)  # 移动到文档末尾
            cursor.movePosition(QTextCursor.MoveOperation.StartOfLine)  # 移动到当前行的开头
            cursor.movePosition(QTextCursor.MoveOperation.EndOfLine)  # 移动到当前行的末尾
            self._日志文本框.setTextCursor(cursor)
            self._日志文本框.insertPlainText(text)  # 在当前行末尾插入文本
        else:
            当前时间 = datetime.datetime.now()
            当前时间字符串 = 当前时间.strftime('%Y-%m-%d %H:%M:%S')
            self._日志文本框.appendPlainText(f'{当前时间字符串} {text}')
